import 'dart:math';
import 'package:ceramics/cache.dart';
import 'package:ceramics/extensions/ab_list_extensions.dart';
import 'package:ceramics/model/ab_like.dart';
import 'package:ceramics/model/ab_oauth.dart';
import 'package:ceramics/util/ab_api.dart';
import 'package:ceramics/util/ab_init_db.dart';
import 'package:ceramics/util/ab_oss_fetch_util.dart';
import 'package:ceramics/util/ab_value_converter.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'ab_singleton.dart';

/// id,video,title,userId,avatar,nickname
class ABVideo {
  int id = -1;
  String? video;
  String? title;
  String? userId;
  String? avatar;
  String? nickname;
  OSSResponse? videoOss;
  OSSResponse? avatarOss;
  int likeCount;
  var commentCount = Rxn<int?>();
  var isLiked = false.obs;
  var isFollowed = false.obs;

  ABVideo({
    required this.id,
    this.video,
    this.title,
    this.userId,
    this.avatar,
    this.nickname,
    this.likeCount = 0,
  });

  static ABVideo fromJson(Map<String, dynamic> json) {
    var model = ABVideo(
      id: valueToInt(json['id']),
      video: valueToString(json['video']),
      title: valueToString(json['title']),
      userId: valueToString(json['userId']),
      avatar: valueToString(json['avatar']),
      nickname: valueToString(json['nickname']),
      likeCount: valueToInt(json['likeCount']),
    )..videoOss = json['video_oss']
      ..commentCount.value = valueToInt(json['commentCount'])
      ..avatarOss = json['avatar_oss'];

    model.isLiked.value = ABSingleton.likes.containsWhere((element) => element.likeId == 'video_${model.id}');
    return model;
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'video': video,
      'title': title,
      'userId': userId,
      'avatar': avatar,
      'likeCount': likeCount,
      'commentCount' : commentCount.value,
      'nickname': nickname,
    };
  }

  static Future<List<ABVideo>> queryVideos() async {
    var result = await abDB.query('videos');
    var blocks = await api.blockList();
    result = result.where((a) => !blocks.containsWhere((b) => b.broadcasterId == a['userId'])).toList();
    ABSingleton.likes.value = await ABLike.queryAllLikes();
    result = await result.replaceOSSURL({
      'video': 'video',
      'avatar': 'image',
    });
    var videos = result.map((e) => ABVideo.fromJson(e)).toList();
    var videoURLs = videos.map((e) => e.videoOss?.mediaUrl ?? '').toList();
    // ktvChannel.invokeMethod('precache',videoURLs);
    for (var video in videos) {
      video.isLiked.value = ABSingleton.likes.containsWhere((element) => element.likeId == 'video_${video.id}');
      ABUser user;
      if (video.userId == null) {
        // 在 ABSingleton.users 中随机挑选一个
        var randomIdx = Random().nextInt(ABSingleton().users.length);
        user = ABSingleton().users[randomIdx];
        video.userId = user.userId;
      } else {
        user = ABSingleton().users.firstWhere((element) => element.userId == video.userId);
      }
      video.nickname ??= user.nickname;
      video.avatar ??= user.avatar;
      video.save();
    }
    return videos;
  }

  Future save() async {
    if (id == -1) {
      id = await abDB.insert('videos', toJson());
    } else {
      await abDB.update('videos', toJson(), where: 'id = ?', whereArgs: [id]);
    }
  }

  static deleteVideosWithUserId(String s) {
    return abDB.delete('videos', where: 'userId = ?', whereArgs: [s]);
  }

  static replaceUsers(List<ABUser> users) async {
    var works = await abDB.query('videos');
    for (var work in works) {
      var userId = work['userId'];
      if (users.isEmpty) {
        break;
      }
      var randomIdx = Random().nextInt(users.length);
      var randomUser = users[randomIdx];
      await abDB.update('videos', {'userId': randomUser.userId, 'nickname': randomUser.nickname, 'avatar': randomUser.avatar}, where: 'userId = ?', whereArgs: [userId]);
      users.removeWhere((element) => element.userId == randomUser.userId);
    }
  }
}